package accs.gui;

import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URI;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import net.miginfocom.swing.MigLayout;
import accs.product.update.UpdateListener;
import accs.product.update.Updater;
import accs.product.update.Version;
import java.awt.Toolkit;

public class UpdateDialog extends JFrame {

	private final JPanel contentPanel = new JPanel();
	private JTextField targetFolderField;
	private JTextField textField_1;
	private JLabel currentFileLabel;
	private JButton targetChooseButton;
	private JButton openBrowserButton;
	private JButton updateButton;
	private JButton finishButton;

	/**
	 * Create the dialog.
	 */
	public UpdateDialog(Version newVersion) {
		setIconImage(Toolkit.getDefaultToolkit().getImage(UpdateDialog.class.getResource("/accs/gui/img/icon.png")));
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent arg0) {
				exit();
			}
		});
		//setModal(true);
		setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		setTitle("Updater: A new version is available!");
		setBounds(100, 100, 599, 300);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(new MigLayout("", "[][grow]", "[][][][][][]"));
		{
			JLabel lblCurrentVersion = new JLabel("Current Version:");
			contentPanel.add(lblCurrentVersion, "cell 0 0,alignx left");
		}
		{
			JLabel lblNewLabel = new JLabel(Version.CURRENT_VERSION.toString());
			contentPanel.add(lblNewLabel, "cell 1 0,growx");
		}
		{
			JLabel lblNewVersion = new JLabel("New Version:");
			contentPanel.add(lblNewVersion, "cell 0 1,alignx left");
		}
		{
			JLabel label = new JLabel(newVersion==null ? "?" : newVersion.toString());
			contentPanel.add(label, "cell 1 1");
		}
		{
			JLabel lblSource = new JLabel("Source:");
			contentPanel.add(lblSource, "cell 0 2,alignx left");
		}
		{
			textField_1 = new JTextField(Updater.AUTOMATIC_UPDATE_URL);
			textField_1.setEditable(false);
			contentPanel.add(textField_1, "cell 1 2,growx");
			textField_1.setColumns(10);
		}
		{
			JLabel lblTargetfolder = new JLabel("Target-Folder:");
			contentPanel.add(lblTargetfolder, "cell 0 3,alignx left");
		}
		{
			targetFolderField = new JTextField(new File("").getAbsolutePath());
			contentPanel.add(targetFolderField, "flowx,cell 1 3,growx");
			targetFolderField.setColumns(10);
		}
		{
			targetChooseButton = new JButton("...");
			targetChooseButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					chooseTargetFolder();
				}
			});
			contentPanel.add(targetChooseButton, "cell 1 3");
		}
		{
			JLabel lblInfo = new JLabel("Info:");
			contentPanel.add(lblInfo, "cell 0 4");
		}
		{
			JLabel lblIfYouHave = new JLabel("If you have problems with the update then download and unzip it yourself.");
			contentPanel.add(lblIfYouHave, "flowx,cell 1 4,growx");
		}
		{
			JLabel lblCurrentFile = new JLabel("Current File:");
			contentPanel.add(lblCurrentFile, "cell 0 5");
		}
		{
			currentFileLabel = new JLabel("-");
			contentPanel.add(currentFileLabel, "cell 1 5,growx");
		}
		{
			openBrowserButton = new JButton("Open in browser");
			openBrowserButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					showUpdatePage();
				}
			});
			contentPanel.add(openBrowserButton, "cell 1 4");
		}
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				updateButton = new JButton("Update!");
				updateButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						startUpdate();
					}
				});
				updateButton.setActionCommand("OK");
				buttonPane.add(updateButton);
				getRootPane().setDefaultButton(updateButton);
			}
			{
				finishButton = new JButton("Finish");
				finishButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						finishUpdate();
					}
				});
				finishButton.setEnabled(false);
				buttonPane.add(finishButton);
			}
		}
		
		pack();
		setLocationRelativeTo(null);
	}
	
	private void chooseTargetFolder() {
		JFileChooser chooser=new JFileChooser();
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		chooser.setSelectedFile(new File(targetFolderField.getText()));
		chooser.showSaveDialog(this);
		
		targetFolderField.setText(chooser.getSelectedFile().getAbsolutePath());
	}
	
	private void showUpdatePage() {
		boolean success=false;
		
		try {
			if(Desktop.isDesktopSupported()) {
				Desktop.getDesktop().browse(new URI(Updater.INTERACTIVE_UPDATE_URL));
				success=true;
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		if(!success) JOptionPane.showMessageDialog(this,"Error during opening the page. Please open the page on your own: "+Updater.INTERACTIVE_UPDATE_URL,"Error",JOptionPane.ERROR_MESSAGE);
	}
	
	private void startUpdate() {
		targetFolderField.setEnabled(false);
		targetChooseButton.setEnabled(false);
		updateButton.setEnabled(false);
		
		new Thread() {
			public void run() {
				try {
					new Updater().downloadAndUnpack(new File(targetFolderField.getText()),new UpdateListener() {
						public void update(String currentFile) {
							currentFileLabel.setText(currentFile);
						}
					});
					
					currentFileLabel.setText("=== Finished ===");
					finishButton.setEnabled(true);
				} catch (Exception e) {
					JOptionPane.showMessageDialog(UpdateDialog.this,e.toString(),"Error during Update",JOptionPane.ERROR_MESSAGE);
					targetFolderField.setEnabled(true);
					targetChooseButton.setEnabled(true);
					updateButton.setEnabled(true);
				}
			}
		}.start();
	}
	
	private void finishUpdate() {
		JOptionPane.showMessageDialog(this,"Please restart the application now!","Update finished",JOptionPane.INFORMATION_MESSAGE);
		System.exit(0);
	}
	
	private void exit() {
		int res=JOptionPane.showConfirmDialog(this,"You must complete the update in order to start the application.\nPress OK to exit anyway.","Updater",JOptionPane.OK_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE);
		if(res==JOptionPane.OK_OPTION) {
			System.exit(0);
		}
	}
}